package com.wskj.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wskj.common.core.domain.entity.SysUser;
import com.wskj.common.core.mybatisplus.core.ServicePlusImpl;
import com.wskj.common.core.page.PagePlus;
import com.wskj.common.core.page.TableDataInfo;
import com.wskj.common.utils.common.AssertUtils;
import com.wskj.common.utils.common.PageUtils;
import com.wskj.common.utils.common.SecurityUtils;
import com.wskj.common.utils.file.ImageUtils;
import com.wskj.common.utils.wx.WechatUtils;
import com.wskj.obs.service.IObsService;
import com.wskj.system.bo.SysShareAddBo;
import com.wskj.system.bo.SysShareEditBo;
import com.wskj.system.bo.SysShareQueryBo;
import com.wskj.system.domain.SysConfig;
import com.wskj.system.domain.SysShare;
import com.wskj.system.mapper.SysCommonMapper;
import com.wskj.system.mapper.SysConfigMapper;
import com.wskj.system.mapper.SysShareMapper;
import com.wskj.system.service.ISysShareService;
import com.wskj.system.service.ISysUserService;
import com.wskj.system.vo.web.SysShareVo;
import com.wskj.workbench.vo.app.AppShareVo;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 分享Service业务层处理
 *
 * @author wsdz
 * @date 2023-02-24
 */
@Service
@AllArgsConstructor(onConstructor_ = {@Lazy})
public class SysShareServiceImpl extends ServicePlusImpl<SysShareMapper, SysShare> implements ISysShareService {


    private final SysCommonMapper sysCommonMapper;


    private final SysConfigMapper sysConfigMapper;


    private final IObsService iObsService;

    private final ISysUserService userService;


    @Override
    public SysShareVo queryById(Long shareId) {
        return getVoById(shareId, SysShareVo.class);
    }

    @Override
    public TableDataInfo<SysShareVo> queryPageList(SysShareQueryBo bo) {
        PagePlus<SysShare, SysShareVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), SysShareVo.class);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<SysShareVo> queryList(SysShareQueryBo bo) {
        return listVo(buildQueryWrapper(bo), SysShareVo.class);
    }

    private LambdaQueryWrapper<SysShare> buildQueryWrapper(SysShareQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysShare> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getBanner()), SysShare::getBanner, bo.getBanner());
        lqw.eq(StrUtil.isNotBlank(bo.getLogo()), SysShare::getLogo, bo.getLogo());
        lqw.eq(StrUtil.isNotBlank(bo.getUrl()), SysShare::getUrl, bo.getUrl());
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(SysShareAddBo bo) {
        SysShare add = BeanUtil.toBean(bo, SysShare.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(SysShareEditBo bo) {
        SysShare update = BeanUtil.toBean(bo, SysShare.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SysShare entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    @Override
    public String importSysShare(List<SysShareVo> sysShareList) {
        AssertUtils.isTrue(CollectionUtils.isNotEmpty(sysShareList), "导入数据不能为空");
        int successNum = 0;
        for (SysShareVo sysShare : sysShareList) {
            SysShare add = BeanUtil.toBean(sysShare, SysShare.class);
            save(add);
            successNum++;
        }
        String msg = String.format("导入完成，共计 %d 条数据，成功 %d 条！", sysShareList.size(), successNum);
        if (successNum != sysShareList.size()) {
            msg = msg + String.format("失败 %d 条！", sysShareList.size() - successNum);
        }
        return msg;
    }

    @Override
    public AppShareVo code() throws Exception {

        SysUser sysUser = userService.getById(SecurityUtils.getUserId());

        String checkPath = sysCommonMapper.selectById(1000092).getCommonValue();
        String envVersion = sysCommonMapper.selectById(1000093).getCommonValue();

        String path = sysCommonMapper.selectById(1000091).getCommonValue();
        byte[] qrCode = WechatUtils.getMiniCode(sysCommonMapper.selectById(1000002).getCommonValue(),
                sysCommonMapper.selectById(1000003).getCommonValue(), path, sysUser.getInviteCode(), Boolean.valueOf(checkPath), envVersion);


        // 小程序码上加文字
        byte[] bytes = ImageUtils.addTextToImage(qrCode, sysUser.getRealName(),sysUser.getInviteCode());
        // 小程序码路径
        String miniPath = uploadToYun(bytes);

        AppShareVo appShareVo = new AppShareVo();
        appShareVo.setMiniPath(miniPath);

        return appShareVo;
    }

    private String uploadToYun(byte[] bytes) throws Exception {

        // 获取文件生成目录
        SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getConfigKey, "qrcode:dest:address"));

        String filePath = sysConfig.getConfigValue() + String.format("/%s/%s.jpg", DateUtil.format(new Date(), "YYYY/MM"), RandomUtil.randomNumbers(6));

        //这里就直接把二进制保存为文件了
        File file = FileUtil.writeBytes(bytes, filePath);
        MultipartFile multipartFile = com.wskj.common.utils.qrcode.FileUtil.transferToMultipartFile(file);

        String path = iObsService.uploadByLocal(multipartFile).get("fullUrl").toString();
        return path;
    }


    @Override
    public boolean houtaiCode(Long[] userIds) throws Exception {


        boolean result = true;
        for (Long userId : userIds) {
            SysUser sysUser = userService.getById(userId);


            String checkPath = sysCommonMapper.selectById(1000092).getCommonValue();
            String envVersion = sysCommonMapper.selectById(1000093).getCommonValue();

            String path = sysCommonMapper.selectById(1000091).getCommonValue();
            byte[] qrCode = WechatUtils.getMiniCode(sysCommonMapper.selectById(1000002).getCommonValue(),
                    sysCommonMapper.selectById(1000003).getCommonValue(), path, sysUser.getInviteCode(), Boolean.valueOf(checkPath), envVersion);


            // 小程序码路径
            String miniPath = uploadToYun(qrCode);

            sysUser.setMiniPath(miniPath);

            result = userService.updateById(sysUser);


        }
        return result;
    }
}
